﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Telerik.Web.Mvc;

namespace Presentation.Web.Admin.Controllers
{
    [HandleError]
    public class GoodsController : Infrastructure.Crosscutting.NetFramework.Controllers.BaseController
    {
        Application.Admin.Goods.IGoodsPicService goodsPicService;

        Application.Admin.Goods.IGoodsService goodsService;

        Application.Admin.Goods.IGoodsImportLogService logService;

        Application.Admin.Sight.ISightPointService sightService;

        Application.Admin.Sight.ISightPointGoodsService sightGoodsService;

        Application.Admin.Pic.IPicInfoService picService;

        public GoodsController(Infrastructure.Crosscutting.NetFramework.IWorkContext work,
            Application.Admin.Goods.IGoodsPicService goodsPic,
            Application.Admin.Goods.IGoodsService goods,
            Application.Admin.Pic.IPicInfoService pic,
            Application.Admin.Goods.IGoodsImportLogService log,
            Application.Admin.Sight.ISightPointService sight,
            Application.Admin.Sight.ISightPointGoodsService sightGoods)
            : base(work)
        {
            if (goodsPic == null)
            {
                throw new ArgumentNullException("goodsPicService is null");
            }
            if (goods == null)
            {
                throw new ArgumentNullException("goodsService is null");
            }
            if (pic == null)
            {
                throw new ArgumentNullException("picService is null");
            }
            if (log == null)
            {
                throw new ArgumentNullException("logService is null");
            }
            if (sight == null)
            {
                throw new ArgumentNullException("sightService is null");
            }
            if (sightGoods == null)
            {
                throw new ArgumentNullException("sightGoodsService is null");
            }
            goodsPicService = goodsPic;
            goodsService = goods;
            picService = pic;
            logService = log;
            sightService = sight;
            sightGoodsService = sightGoods;
        }

        #region goods

        public ActionResult Index()
        {
            var data = this.GetGoodsTrueState();
            return View(data.ToDto());
        }

        [GridAction]
        public JsonResult AjaxIndex(string searchKey)
        {
            var data = this.GetGoodsTrueState();
            if (!string.IsNullOrEmpty(searchKey))
            {
                data = data.Where(e => e.Name.Contains(searchKey));
            }
            var dto = data.ToDto();
            var model = new GridModel<Domain.Dto.GoodsDto>
            {
                Data = dto,
                Total = dto.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult Add(Domain.Dto.GoodsDto dto)
        {
            dto.AddTime = System.DateTime.Now;
            dto.AddTime = System.DateTime.Now;
            dto.AudTime = null;
            dto.DeleteTime = null;
            dto.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
            dto.IsAud = true;
            dto.IsDelete = false;
            dto.IsTop = false;
            dto.IsVouch = false;
            dto.Name = string.IsNullOrEmpty(dto.Name) ? "" : dto.Name.Trim();
            //dto.Price
            //dto.Remark
            dto.SortNum = 0;
            dto.TopTime = null;
            dto.UserId = this.WorkContext.CurrentUser.Id;
            dto.UserName = this.WorkContext.CurrentUser.UserName;
            dto.VouchTime = null;
            var entity = dto.ToEntity();
            goodsService.Add(entity, this.WorkContext.CurrentUser);
            var data = this.GetGoodsTrueState();
            var model = new GridModel<Domain.Dto.GoodsDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [GridAction]
        [HttpPost]
        public JsonResult Delete(int id)
        {
            var delete = goodsService.Get(id);
            if (delete != null)
            {
                goodsService.DeleteTrue(delete, this.WorkContext.CurrentUser);
            }
            var data = this.GetGoodsTrueState().ToDto();
            return Json(data, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public JsonResult MulDelete(FormCollection del)
        {
            var res = false;
            var message = "";
            var selectedList = del.GetValues("selectRow");
            if (selectedList != null && selectedList.Count() > 0)
            {
                res = goodsService.DeleteTrue(selectedList.ToIntList(), this.WorkContext.CurrentUser);
                message = res == true ? "" : "删除失败了，T_T";
            }
            //返回空，是为了不再请求数据，因为他自己会重新binding的
            return Json(new { success = res, message = message }, JsonRequestBehavior.AllowGet);
        }

        [GridAction]
        [HttpPost]
        public JsonResult Edit(Domain.Dto.GoodsDto dto)
        {
            if (dto.Id > 0)
            {
                var entity = goodsService.Get(dto.Id);
                if (entity != null && entity.Id > 0)
                {
                    entity.Name = string.IsNullOrEmpty(dto.Name) ? "" : dto.Name.Trim();
                    entity.Remark = string.IsNullOrEmpty(dto.Remark) ? "" : dto.Remark.Trim();
                    entity.Price = dto.Price;
                    entity.DiscountRemark = dto.DiscountRemark;
                    goodsService.Modify(entity, this.WorkContext.CurrentUser);
                }
            }
            var data = this.GetGoodsTrueState();
            var model = new GridModel<Domain.Dto.GoodsDto>
            {
                Data = data.ToDto(),
                Total = data.Count()
            };
            return new JsonResult { Data = model, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
        }

        [HttpGet]
        public JsonResult Search(string term)
        {
            if (!string.IsNullOrEmpty(term))
            {
                var data = this.GetGoodsTrueState().Where(e => e.Name.Contains(term.Trim()))
                            .OrderBy(e => e.Id).Take(10)
                            .Select(e => e.Name).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
            else
            {
                var data = this.GetGoodsTrueState().OrderBy(e => e.Id).Take(10)
                            .Select(e => e.Name).Distinct();
                return Json(data.ToList(), JsonRequestBehavior.AllowGet);
            }
        }

        #endregion

        #region goods pic

        public ViewResult GoodsPicIndex(int id)
        {
            var goodPicIdList = goodsPicService.GetList().Where(e => e.State == true)
                .Where(e => e.GoodsId == id).Select(e => e.PicInfoId);
            var data = picService.GetList().Where(e => goodPicIdList.Contains(e.Id))
                .OrderByDescending(e => e.Id);
            var current = goodsService.Get(id);
            ViewBag.current = current;
            return View(data.ToDto());
        }

        #endregion

        #region goods import

        public ActionResult ImportGoods(HttpPostedFileBase importGoodsFile, string key)
        {
            var fileName = importGoodsFile.FileName;
            var suffix = System.IO.Path.GetExtension(fileName);
            var newFileName = System.DateTime.Now.ToFileTime() + suffix;
            var prePath = PreAdminConfigSettingService.ExcelSavePath.Substring(1);
            var webFullPath = prePath + newFileName;
            var savePath = System.IO.Path.Combine(Server.MapPath(PreAdminConfigSettingService.ExcelSavePath), newFileName);
            importGoodsFile.SaveAs(savePath);
            using (var excelService = new Infrastructure.Crosscutting.Comm.Service.ExcelService(savePath))
            {
                var excelData = excelService.ReadTable("Sheet1");
                //写入导入记录，
                #region add import log

                Domain.Entity.GoodsImportLog log = new Domain.Entity.GoodsImportLog();
                log.AddTime = System.DateTime.Now;
                log.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                log.Name = newFileName;
                log.PhyPrePath = prePath;
                log.SortNum = 0;
                log.SourceName = fileName;
                log.State = true;
                log.WebFullPath = webFullPath;
                log.WebPrePath = prePath;
                logService.Add(log, this.WorkContext.CurrentUser);
                #endregion

                //添加excel中数据
                if (excelData != null && excelData.Rows.Count > 0)
                {
                    var count = excelData.Rows.Count;
                    for (int i = 1; i < count; i++)
                    {
                        var idStr = excelData.Rows[i][0].ToString();
                        var id = 0;
                        int.TryParse(idStr, out id);
                        var name = excelData.Rows[i][1].ToString();
                        var remark = excelData.Rows[i][2].ToString();
                        var priceStr = excelData.Rows[i][3].ToString();
                        var price = 0.0;
                        double.TryParse(priceStr, out price);
                        var discount = excelData.Rows[i][4].ToString();
                        var sightName = excelData.Rows[i][5].ToString();

                        Domain.Entity.Goods temp = null;
                        if (string.Compare(key, "keyName", false) == 0)
                        {
                            if (string.IsNullOrEmpty(name))
                            {
                                continue;
                            }
                            temp = goodsService.GetList().Where(e => e.Name == name).FirstOrDefault();
                            if (temp != null)
                            {
                                temp.Remark = remark;
                                temp.Price = price;
                                temp.DiscountRemark = discount;
                                this.InitGoods(temp);
                                goodsService.Modify(temp, this.WorkContext.CurrentUser);
                                this.AddToSightGooods(sightName, temp);
                            }
                            else
                            {
                                temp = new Domain.Entity.Goods();
                                temp.Name = name;
                                temp.Remark = remark;
                                temp.Price = price;
                                temp.DiscountRemark = discount;
                                this.InitGoods(temp);
                                goodsService.Add(temp, this.WorkContext.CurrentUser);
                                this.AddToSightGooods(sightName, temp);
                            }
                        }
                        else if (string.Compare(key, "keyId", false) == 0)
                        {
                            if (id <= 0 || string.IsNullOrEmpty(name))
                            {
                                continue;
                            }
                            temp = goodsService.GetList().Where(e => e.Id == id).FirstOrDefault();
                            if (temp != null)
                            {
                                temp.Name = name;
                                temp.Remark = remark;
                                temp.Price = price;
                                temp.DiscountRemark = discount;
                                this.InitGoods(temp);
                                goodsService.Modify(temp, this.WorkContext.CurrentUser);
                                this.AddToSightGooods(sightName, temp);
                            }
                            else
                            {
                                temp = new Domain.Entity.Goods();
                                temp.Name = name;
                                temp.Remark = remark;
                                temp.Price = price;
                                temp.DiscountRemark = discount;
                                this.InitGoods(temp);
                                goodsService.Add(temp, this.WorkContext.CurrentUser);
                                this.AddToSightGooods(sightName, temp);
                            }
                        }
                    }
                }
            }
            return RedirectToAction("Index");
        }

        private void InitGoods(Domain.Entity.Goods temp)
        {
            temp.AddTime = System.DateTime.Now;
            temp.AudTime = null;
            temp.DeleteTime = null;
            temp.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
            temp.IsAud = false;
            temp.IsDelete = false;
            temp.IsTop = false;
            temp.IsVouch = false;
            temp.SortNum = 0;
            temp.State = true;
            temp.TopTime = null;
            temp.UserId = this.WorkContext.CurrentUser.Id;
            temp.UserName = this.WorkContext.CurrentUser.UserName;
            temp.VouchTime = null;
        }

        #endregion

        #region util

        protected void AddToSightGooods(string sightName, Domain.Entity.Goods temp)
        {
            if (!string.IsNullOrEmpty(sightName))
            {
                var sight = sightService.GetList().Where(e => e.Name == sightName).FirstOrDefault();
                if (sight != null)
                {
                    var isExist = sightGoodsService.GetList().Where(e => e.SightId == sight.Id)
                        .Where(e => e.GoodsId == temp.Id).Any();
                    if (!isExist)
                    {
                        var sightGoods = new Domain.Entity.SightPointGoods();
                        sightGoods.AddTime = System.DateTime.Now;
                        sightGoods.GoodsId = temp.Id;
                        sightGoods.IpAddress = Infrastructure.Crosscutting.Comm.Service.StringService.GetRealIP();
                        sightGoods.SightId = sight.Id;
                        sightGoods.SortNum = 0;
                        sightGoods.State = true;
                        sightGoodsService.Add(sightGoods, this.WorkContext.CurrentUser);
                    }
                }
            }
        }

        protected IQueryable<Domain.Entity.Goods> GetGoodsTrueState()
        {
            var data = goodsService.GetList().Where(e => e.State == true)
                .OrderByDescending(e => e.Id);
            return data;
        }

        #endregion
    }
}
